package com.e3.basdoc.cust.server;

import java.util.ArrayList;
import java.util.List;

import com.e3.basdoc.cust.client.CustHelper;
import com.e3.basdoc.cust.client.CustRPCService;
import com.e3.basdoc.cust.model.CustAccountModel;
import com.e3.basdoc.cust.model.CustModel;
import com.e3.basdoc.cust.model.CustQC;
import com.e3.basdoc.region.model.RegionModel;
import com.e3.basdoc.region.server.RegionServiceClient;
import com.e3.core.base.ServiceException;
import com.e3.core.utils.PKgen;
import com.e3.web.core.client.WebException;
import com.e3.web.core.server.GwtRPCAction;
import com.e3.web.core.server.GwtRPCExecutor;
import com.e3.web.core.server.GwtRPCVoidExecutor;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;

public class CustRPCServiceImpl extends GwtRPCAction implements CustRPCService {

	public CustModel newCust(final CustModel custModel) throws WebException {
		return new GwtRPCExecutor<CustModel>() {

			@Override
			public CustModel execute() throws ServiceException, Exception {
				return CustServiceClient.getCustService().newCust(custModel);
			}

		}.doExecute();
	}

	public List<CustModel> getCustsByCondition(final CustQC custQC) throws WebException {
		return new GwtRPCExecutor<List<CustModel>>() {

			@Override
			public List<CustModel> execute() throws ServiceException, Exception {
				List<CustModel> custs = CustServiceClient.getCustQueryService().getCustByCondition(custQC);
				if (custs == null || custs.size() <= 0) {
					return custs;
				}
				fillRegion(custs);
				fillParentCust(custs);
				return custs;
			}

		}.doExecute();
	}

	public CustModel modifyCust(final CustModel custModel) throws WebException {
		return new GwtRPCExecutor<CustModel>() {

			@Override
			public CustModel execute() throws ServiceException, Exception {
				return CustServiceClient.getCustService().modifyCust(custModel);
			}

		}.doExecute();
	}

	public void deleteCusts(final List<CustModel> custModels) throws WebException {
		new GwtRPCVoidExecutor() {

			@Override
			public void execute() throws ServiceException, Exception {
				CustServiceClient.getCustService().deleteCusts(custModels);
			}

		}.doExecute();
	}

	public List<CustModel> getCustChildren(final CustModel custModel) throws WebException {
		return new GwtRPCExecutor<List<CustModel>>() {
			@Override
			public List<CustModel> execute() throws ServiceException, Exception {
				List<CustModel> models = new ArrayList<CustModel>();
				if (custModel == null) {
					CustModel model = CustHelper.INSTANCE.createRootModel();
					models.add(model);
					return models;
				}

				CustModel qModel = custModel;
				if (CustHelper.INSTANCE.isRootModel(qModel)) {
					qModel = null;
				}
				List<CustModel> result = CustServiceClient.getCustQueryService().getCustChildren(qModel);
				CustHelper.INSTANCE.setCustRelations(custModel, result);
				fillRegion(result);
				return result;
			}

		}.doExecute();
	}

	public CustModel getCustById(final Long id) throws WebException {
		return new GwtRPCExecutor<CustModel>() {

			@Override
			public CustModel execute() throws ServiceException, Exception {
				return CustServiceClient.getCustQueryService().getCustModelById(id);
			}

		}.doExecute();
	}

	private void fillRegion(List<CustModel> custs) throws Exception {
		if(custs==null||custs.isEmpty()){
			return;
		}
		// 填充Cust的所在地区
		List<Long> regionIds = new ArrayList<Long>(custs.size());
		for (CustModel cust : custs) {
			Long regionId = cust.getRegionId();
			if (!regionIds.contains(regionId)) {
				regionIds.add(regionId);
			}
		}
		if (!regionIds.isEmpty()) {
			Long[] ids = new Long[regionIds.size()];
			regionIds.toArray(ids);
			List<RegionModel> regions = RegionServiceClient.getRegionQueryService().getRegionModelByIds(ids);
			for (CustModel cust : custs) {
				Long regionId = cust.getRegionId();
				for (RegionModel region : regions) {
					Long id = region.getId();
					if (regionId.equals(id)) {
						cust.setRegion(region);
						break;
					}
				}
			}
		}
	}

	private void fillParentCust(List<CustModel> custs) throws Exception {
		// 填充Cust的上级Cust
		List<Long> parentIds = new ArrayList<Long>(custs.size());
		for (CustModel cust : custs) {
			if (!CustHelper.INSTANCE.isTopModel(cust)) {
				Long parentId = cust.getParentId();
				if (!parentIds.contains(parentId)) {
					parentIds.add(parentId);
				}
			}
		}
		if (!parentIds.isEmpty()) {
			Long[] ids = new Long[parentIds.size()];
			parentIds.toArray(ids);
			List<CustModel> parentCusts = CustServiceClient.getCustQueryService().getCustModelByIds(ids);
			for (CustModel cust : custs) {
				Long pID = cust.getParentId();
				for (CustModel custModel : parentCusts) {
					Long id = custModel.getId();
					if (pID.equals(id)) {
						cust.setParentCust(custModel);
						break;
					}
				}
			}
		}
	}

	public PagingLoadResult<CustModel> getPagingCusts(final PagingLoadConfig config) throws WebException {
		final CustQC qc = config.get("LOAD_CONDTION");
		List<CustModel> models = new GwtRPCExecutor<List<CustModel>>() {
			int start = config.getOffset();
			int max = config.getLimit();
			@Override
			public List<CustModel> execute() throws ServiceException,	Exception {
				List<CustModel> custs = CustServiceClient.getCustQueryService().getPagingCust(qc, start, max);
				if (custs == null || custs.isEmpty()) {
					return custs;
				}
				return custs;
			}
			
		}.doExecute();
		if(models == null||models.isEmpty()){
			return new BasePagingLoadResult<CustModel>(new ArrayList<CustModel>());
		}
		
		long size = new GwtRPCExecutor<Long>(){
			@Override
			public Long execute() throws ServiceException, Exception {
				return CustServiceClient.getCustQueryService().getCustSizeByCondition(qc);
			}
			
		}.doExecute();
		
		return new BasePagingLoadResult<CustModel>(models, config.getOffset(), (int)size);

	}

	public CustAccountModel createAccountModelInstance() throws WebException {
		CustAccountModel model = new CustAccountModel();
		model.setModelId(""+PKgen.getInstance().nextPK());
		return model;
	}

}
